package com.chucang.shucang.common.oss.utils;

import com.chucang.shucang.common.oss.config.MinioConfig;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.PostPolicy;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import io.minio.http.Method;
import lombok.Cleanup;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author flitsneak
 * @email flitsneak@gmail.com
 * @date 2022/10/3 0:33
 * @description
 */
@Component
@RequiredArgsConstructor
public class OssUtil {
    private final MinioClient minioClient;

    private final MinioConfig minioConfig;

    /**
     * 获取上传文件临时签名
     *
     * @param fileName 文件名
     * @param time     时间
     * @return m
     */
    public Map<String, String> getPolicy(String fileName, ZonedDateTime time) {
        PostPolicy postPolicy = new PostPolicy(minioConfig.getBucketName(), time);
        postPolicy.addEqualsCondition("key", fileName);
        try {
            Map<String, String> map = minioClient.getPresignedPostFormData(postPolicy);
            HashMap<String, String> map1 = new HashMap<>();
            map.forEach((k, v) ->
                    map1.put(k.replace("-", ""), v)
            );
            map1.put("host", minioConfig.getEndPoint() + "/" + minioConfig.getBucketName());
            return map1;
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                 InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException |
                 XmlParserException e) {
            e.printStackTrace();
        }
        return Collections.emptyMap();
    }

    /**
     * 获取上传文件地址
     *
     * @param objectName name
     * @param method     m
     * @param time       t
     * @param timeUnit   单位
     * @return s
     */
    public String getPolicyUrl(String objectName, Method method, int time, TimeUnit timeUnit) {
        try {
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(method)
                    .bucket(minioConfig.getBucketName())
                    .object(objectName)
                    .expiry(time, timeUnit).build());
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                 InvalidResponseException | IOException | NoSuchAlgorithmException | XmlParserException |
                 ServerException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 上传文件
     *
     * @param file     f
     * @param fileName name
     */
    public void upload(MultipartFile file, String fileName) {
        // 使用putObject上传一个文件到存储桶中。
        try {
            @Cleanup
            InputStream inputStream = file.getInputStream();
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build());
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                 InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException |
                 XmlParserException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据文件名获取文件访问地址
     *
     * @param objectName 文件名
     * @param time       t
     * @param timeUnit   t
     * @return s
     */
    public String getUrl(String objectName, int time, TimeUnit timeUnit) {
        String url = null;
        try {
            url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(minioConfig.getBucketName())
                    .object(objectName)
                    .expiry(time, timeUnit).build());
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                 InvalidResponseException | IOException | NoSuchAlgorithmException | XmlParserException |
                 ServerException e) {
            e.printStackTrace();
        }
        return url;
    }

    public String getAbsoluteUrl(String objectName) {
        return minioConfig.getBucketName() + "/" + objectName;
    }

}
